package thread;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * NEW->RUNNABLE->WAITING->RUNNABLE->TERMINATED
 */
public class ThreadStateNRWRTLock {
    //锁
    private static Lock lock = new ReentrantLock();
    //锁定标志
    private volatile static boolean lockFlag = true;
    //执行顺序
    private volatile static int order = 0;

    public static void main(String[] args) {
        //展示线程
        Thread showThread = new Thread(new Task());
        ThreadUtils.print(showThread.getName(), showThread.getState());
        showThread.start();
        ThreadUtils.print(showThread.getName(), showThread.getState());
        //辅助线程，制造synchronized状态。
        Thread assistantThread = new Thread(new SynTask());
        assistantThread.start();
        //循环读取展示线程状态，直到读到展示线程状态为BLOCKED，才让辅助线程退出同步。
        while (true) {
            if (showThread.getState() == Thread.State.WAITING) {
                ThreadUtils.print(showThread.getName(), Thread.State.WAITING);
                lockFlag = false;
                break;
            }
        }
        try {
            assistantThread.join();
            showThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //线程执行完毕打印状态。
        ThreadUtils.print(showThread.getName(), showThread.getState());
    }

    private static class SynTask implements Runnable {
        @Override
        public void run() {
            while (true) {
                //保证先进入同步范围。
                if (order == 0) {
                    //加锁
                    lock.lock();
                    try {
                        order = 1;
                        while (lockFlag) {
                            try {
                                Thread.sleep(10);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    } finally {
                        lock.unlock();
                    }
                    break;
                }
            }
        }
    }

    private static class Task implements Runnable {
        @Override
        public void run() {
            while (true) {
                //保证后进入同步范围。
                if (order == 1) {
                    lock.lock();
                    try {
                        ThreadUtils.print(Thread.currentThread().getName(), Thread.currentThread().getState());
                    } finally {
                        lock.unlock();
                    }
                    break;
                }
            }
        }
    }

}
